package com.acme;

public class Test {

    // http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html
    public static void main(String[] args) {

        // assignment narrowing primitive conversion - int to byte,
        // need explicit cast to byte, or change type v2 to int
        int v1 = 3;
        byte v2 = (byte) v1;
        System.out.println(v2);

        // assignment narrowing primitive conversion - int to byte,
        // need explicit cast to byte, or change type v3 to int
        // Quote from oracle doc specs:
        // "A narrowing conversion of a signed integer to an integral type T
        // simply discards all but the n lowest order bits, where n is the
        // number of bits used to represent type T. In addition to a possible
        // loss of information about the magnitude of the numeric value, this
        // may cause the sign of the resulting value to differ from the sign of
        // the input value."
        // therefore 100000000 becomes 00000000
        v1 = 256;
        byte v3 = (byte) v1;
        System.out.println(v3);

        // Quote:
        // "A widening conversion of a char to an integral type T zero-extends
        // the
        // representation of the char value to fill the wider format."
        // just a char 's' to int implicit widening conversion
        // char 's' is a unicode code '\u0073' hex, 115 dec
        int v4 = 's';
        System.out.println(v4);

        // byte 115 == char '\u0073';
        // printed "Equals", binary numeric promotion
        // widening primitive conversion, promoted to int == int conversion
        byte v5 = 115;
        if (v5 == 's') {
            System.out.println("Equals");
        }

        // widening primitive conversion int to double (4 to 4.0)
        // printed: 4.0
        System.out.println((double) 4);

        // widening primitive conversion int to double (5 to 5.0)
        // implicit cast to double, cast (double) is permitted but not required
        double d = 5;
        // binary numeric promotion, widening primitive conversion
        // "If either operand is of type double, the other is converted to double."
        // System.out.println(d + (double)1);
        // printed: 6.0
        System.out.println(d + 1);

        // boolean can take only 'true' or 'false'
        // in java you can't cast any numeric type to boolean
        // you can do "boolean b = (v4 != 0);", but it's ugly
        // boolean b = v4;

        // cannot convert String to short
        // short v6 = "short";

        // Quote:
        // "A narrowing primitive conversion from double to float is governed by
        // the IEEE 754 rounding rules. This conversion can lose
        // precision, but also lose range, resulting in a float zero from a
        // nonzero double and a float infinity from a finite double. A double
        // NaN is converted to a float NaN and a double infinity is converted to
        // the same-signed float infinity."
        // need explicit cast to float, or type 3.67f
        float v7 = 3.67f;

        // because this is widening primitive conversion int to float (3 to
        // 3.0f)
        // cast (float) is permitted but not required
        float v9 = 3;

        // assignment narrowing primitive conversion - float to int,
        // need explicit cast to int, or change type v8 to float, lose precision
        // 3.67f becomes 3
        int v8 = (int) v7;

        // incorrect declaration (type 'int[]') or construction (returns double[] array 'new double[]')
        // String "27" cannot be converted to int, you need use
        // Integer.parseInt("27") or something like that, or just use 27 integer value
        // correct is:
        // int array[] = new int[27]; or double array[] = new double[27];

        // int array[] = new double["27"];

    }
}
